home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP06.ZIP / CHAP06 / EDATAOBJ / DATAOBJ.CPP < prev    next >
C/C++ Source or Header  |  1993-04-14  |  8KB  |  340 lines

  1. /*
  2.  * DATAOBJ.CPP
  3.  * Data Object for Chapter 6
  4.  *
  5.  * Implementation of the CDataObject and CImpIDataObject that work
  6.  * in either an EXE or DLL.
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "dataobj.h"
  19.  
  20. extern HINSTANCE   g_hInst;
  21.  
  22. DWORD              g_dwID=0;
  23.  
  24. //Names of data sizes
  25. static char  * rgszSize[3]={"Small", "Medium", "Large"};
  26.  
  27.  
  28.  
  29. /*
  30.  * CDataObject::CDataObject
  31.  * CDataObject::~CDataObject
  32.  *
  33.  * Parameters (Constructor):
  34.  *  punkOuter       LPUNKNOWN of a controlling unknown, if it exists.
  35.  *  pfnDestroy      LPFNDESTROYED to call when an object is destroyed.
  36.  *  iSize           UINT specifying the size of the data set to use.
  37.  */
  38.  
  39. CDataObject::CDataObject(LPUNKNOWN punkOuter, LPFNDESTROYED pfnDestroy
  40.     , UINT iSize)
  41.     {
  42.     UINT        i;
  43.  
  44.     m_cRef=0;
  45.     m_punkOuter=punkOuter;
  46.     m_pfnDestroy=pfnDestroy;
  47.     m_iSize=iSize;
  48.  
  49.     m_hWndAdvise=NULL;
  50.     m_dwAdvFlags=ADVF_NODATA;
  51.  
  52.     //NULL any contained interfaces initially.
  53.     m_pIDataObject=NULL;
  54.     m_pIDataAdviseHolder=NULL;
  55.  
  56.     //Initilize the FORMATETCs arrays we use for ::EnumFormatEtc
  57.     m_cfeGet=CFORMATETCGET;
  58.  
  59.     //These macros are in bookguid.h
  60.     SETDefFormatEtc(m_rgfeGet[0], CF_METAFILEPICT, TYMED_MFPICT);
  61.     SETDefFormatEtc(m_rgfeGet[1], CF_BITMAP, TYMED_GDI);
  62.     SETDefFormatEtc(m_rgfeGet[2], CF_TEXT, TYMED_HGLOBAL);
  63.  
  64.     for (i=0; i < DOSIZE_CSIZES; i++)
  65.         m_rghBmp[i]=NULL;
  66.  
  67.     return;
  68.     }
  69.  
  70.  
  71. CDataObject::~CDataObject(void)
  72.     {
  73.     UINT        i;
  74.  
  75.     for (i=0; i < DOSIZE_CSIZES; i++)
  76.         {
  77.         if (NULL!=m_rghBmp[i])
  78.             DeleteObject(m_rghBmp[i]);
  79.         }
  80.  
  81.     if (NULL!=m_pIDataAdviseHolder)
  82.         m_pIDataAdviseHolder->Release();
  83.  
  84.     if (NULL!=m_pIDataObject)
  85.         delete m_pIDataObject;
  86.  
  87.     if (NULL!=m_hWndAdvise)
  88.         DestroyWindow(m_hWndAdvise);
  89.  
  90.     return;
  91.     }
  92.  
  93.  
  94.  
  95. /*
  96.  * CDataObject::FInit
  97.  *
  98.  * Purpose:
  99.  *  Performs any intiailization of a CDataObject that's prone to failure
  100.  *  that we also use internally before exposing the object outside.
  101.  *
  102.  * Parameters:
  103.  *  None
  104.  *
  105.  * Return Value:
  106.  *  BOOL            TRUE if the function is successful, FALSE otherwise.
  107.  */
  108.  
  109. BOOL CDataObject::FInit(void)
  110.     {
  111.     LPUNKNOWN       pIUnknown=(LPUNKNOWN)this;
  112.     UINT            i;
  113.     char            szTemp[80];
  114.     UINT            cy;
  115.  
  116.     if (NULL!=m_punkOuter)
  117.         pIUnknown=m_punkOuter;
  118.  
  119.     //Allocate contained interfaces.
  120.     m_pIDataObject=new CImpIDataObject(this, pIUnknown);
  121.  
  122.     if (NULL==m_pIDataObject)
  123.         return FALSE;
  124.  
  125.     for (i=0; i < DOSIZE_CSIZES; i++)
  126.         {
  127.         m_rghBmp[i]=LoadBitmap(g_hInst, MAKEINTRESOURCE(i+IDB_MIN));
  128.  
  129.         if (NULL==m_rghBmp[i])
  130.             return FALSE;
  131.         }
  132.  
  133.  
  134.     /*
  135.      * Register the Advise window class first time through (g_dwID==0)
  136.      */
  137.  
  138.     if (0==g_dwID)
  139.         {
  140.         WNDCLASS    wc;
  141.  
  142.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  143.         wc.lpfnWndProc    = AdvisorWndProc;
  144.         wc.cbClsExtra     = 0;
  145.         wc.cbWndExtra     = sizeof(LPCDataObject);
  146.         wc.hInstance      = g_hInst;
  147.         wc.hIcon          = LoadIcon(g_hInst, MAKEINTRESOURCE(IDR_ADVISORICON));
  148.         wc.hCursor        = NULL;
  149.         wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  150.         wc.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU);
  151.         wc.lpszClassName  = "Advisor";
  152.  
  153.         if (!RegisterClass(&wc))
  154.             return FALSE;
  155.         }
  156.  
  157.     /*
  158.      * Create an advise window with a unique caption:
  159.      * "Data Object Advisor #xx" where xx is counted globally
  160.      * every time a CDataObject is created.
  161.      */
  162.  
  163.     g_dwID++;
  164.    #ifdef EXEDATAOBJECT
  165.     wsprintf(szTemp, "%s EXE Advisor #%lu", (LPSTR)rgszSize[m_iSize], g_dwID);
  166.    #else
  167.     wsprintf(szTemp, "%s DLL Advisor #%lu", (LPSTR)rgszSize[m_iSize], g_dwID);
  168.    #endif
  169.  
  170.     cy=(GetSystemMetrics(SM_CYBORDER)*2)+GetSystemMetrics(SM_CYMENU)
  171.         + GetSystemMetrics(SM_CYCAPTION);
  172.  
  173.     m_hWndAdvise=CreateWindow("Advisor", szTemp
  174.         , WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_BORDER | WS_VISIBLE
  175.         , CW_USEDEFAULT, CW_USEDEFAULT, 200, cy, HWND_DESKTOP
  176.         , NULL, g_hInst, this);
  177.  
  178.     if (NULL==m_hWndAdvise)
  179.         return FALSE;
  180.  
  181.     return TRUE;
  182.     }
  183.  
  184.  
  185.  
  186.  
  187.  
  188. /*
  189.  * CDataObject::QueryInterface
  190.  * CDataObject::AddRef
  191.  * CDataObject::Release
  192.  *
  193.  * Purpose:
  194.  *  IUnknown members for CDataObject object.
  195.  */
  196.  
  197. STDMETHODIMP CDataObject::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  198.     {
  199.     *ppv=NULL;
  200.  
  201.     if (IsEqualIID(riid, IID_IUnknown))
  202.         *ppv=(LPVOID)this;
  203.  
  204.     if (IsEqualIID(riid, IID_IDataObject))
  205.         *ppv=(LPVOID)m_pIDataObject;
  206.  
  207.     //AddRef any interface we'll return.
  208.     if (NULL!=*ppv)
  209.         {
  210.         ((LPUNKNOWN)*ppv)->AddRef();
  211.         return NOERROR;
  212.         }
  213.  
  214.     return ResultFromScode(E_NOINTERFACE);
  215.     }
  216.  
  217.  
  218. STDMETHODIMP_(ULONG) CDataObject::AddRef(void)
  219.     {
  220.     return ++m_cRef;
  221.     }
  222.  
  223.  
  224. STDMETHODIMP_(ULONG) CDataObject::Release(void)
  225.     {
  226.     ULONG       cRefT;
  227.  
  228.     cRefT=--m_cRef;
  229.  
  230.     if (0==m_cRef)
  231.         {
  232.         /*
  233.          * Tell the housing that an object is going away so it can
  234.          * shut down if appropriate.
  235.          */
  236.         if (NULL!=m_pfnDestroy)
  237.             (*m_pfnDestroy)();
  238.  
  239.         delete this;
  240.         }
  241.  
  242.     return cRefT;
  243.     }
  244.  
  245.  
  246.  
  247.  
  248.  
  249. /*
  250.  * AdvisorWndProc
  251.  *
  252.  * Purpose:
  253.  *  Standard window class procedure.
  254.  */
  255.  
  256. LRESULT FAR PASCAL __export AdvisorWndProc(HWND hWnd, UINT iMsg
  257.     , WPARAM wParam, LPARAM lParam)
  258.     {
  259.     LPCDataObject   pDO;
  260.     DWORD           i;
  261.     DWORD           iAdvise;
  262.     DWORD           dwTime;
  263.     DWORD           dwAvg;
  264.     char            szTime[128];
  265.     char            szTitle[80];
  266.     HCURSOR         hCur, hCurT;
  267.  
  268.     //This will be valid for all messages except WM_NCCREATE
  269.     pDO=(LPCDataObject)GetWindowLong(hWnd, 0);
  270.  
  271.     switch (iMsg)
  272.         {
  273.         case WM_NCCREATE:
  274.             pDO=(LPCDataObject)((LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
  275.  
  276.             SetWindowLong(hWnd, 0, (LONG)pDO);
  277.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  278.  
  279.         case WM_CLOSE:
  280.             //Eat to forbid task manager from closing us.
  281.             return 0L;
  282.  
  283.         case WM_COMMAND:
  284.             if (NULL==pDO->m_pIDataAdviseHolder)
  285.                 break;
  286.  
  287.             //Send IAdviseSink::OnDataChange many times.
  288.             i=(DWORD)(LOWORD(wParam)-IDM_ADVISEITERATIONSMIN+1);
  289.             iAdvise=(i*i)*16;
  290.  
  291.             hCur=LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
  292.             hCurT=SetCursor(hCur);
  293.             ShowCursor(TRUE);
  294.  
  295.             dwTime=GetTickCount();
  296.  
  297.             i=0;
  298.             while (TRUE)
  299.                 {
  300.                #ifdef EXEDATAOBJECT
  301.                #ifndef WIN32
  302.                 MSG     msg;
  303.  
  304.                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  305.                     {
  306.                     TranslateMessage(&msg);
  307.                     DispatchMessage(&msg);
  308.                     }
  309.                 else
  310.                #endif
  311.                #endif
  312.                     {
  313.                     pDO->m_pIDataAdviseHolder->SendOnDataChange(
  314.                         pDO->m_pIDataObject, 0, ADVF_NODATA);
  315.  
  316.                     if (++i >= iAdvise)
  317.                         break;
  318.                     }
  319.                 }
  320.  
  321.             dwTime=GetTickCount()-dwTime;
  322.             dwAvg=dwTime/iAdvise;
  323.  
  324.             SetCursor(hCurT);
  325.             ShowCursor(FALSE);
  326.  
  327.             wsprintf(szTime, "Total\t=%lu milliseconds\n\rAverage\t=%lu milliseconds"
  328.                 , dwTime, dwAvg);
  329.  
  330.             GetWindowText(hWnd, szTitle, sizeof(szTitle));
  331.             MessageBox(hWnd, szTime, szTitle, MB_OK);
  332.             break;
  333.  
  334.         default:
  335.             return (DefWindowPro